package main

type MyCircularDeque struct {
	Size int
	Cap  int
	Head *Node
	Tail *Node
}

type Node struct {
	Val  int
	Pre  *Node
	Next *Node
}

func Constructor(k int) MyCircularDeque {
	tail := &Node{Val: -1, Pre: nil, Next: nil}
	head := &Node{Val: -1, Pre: nil, Next: nil}
	head.Next = tail
	tail.Pre = head
	return MyCircularDeque{Size: 0, Cap: k, Head: head, Tail: tail}
}

func (this *MyCircularDeque) InsertFront(value int) bool {
	if this.Size < this.Cap {
		cur := &Node{Val: value, Pre: this.Head, Next: this.Head.Next}
		this.Head.Next.Pre = cur
		this.Head.Next = cur

		this.Size++
		return true
	}
	return false

}

func (this *MyCircularDeque) InsertLast(value int) bool {

	if this.Size < this.Cap {
		cur := &Node{Val: value, Pre: this.Tail.Pre, Next: this.Tail}
		this.Tail.Pre.Next = cur
		this.Tail.Pre = cur

		this.Size++
		return true
	}
	return false
}

func (this *MyCircularDeque) DeleteFront() bool {
	if this.Size > 0 {
		this.Head.Next.Next.Pre = this.Head
		this.Head.Next = this.Head.Next.Next

		this.Size--
		return true
	}
	return false

}

func (this *MyCircularDeque) DeleteLast() bool {
	if this.Size > 0 {
		this.Tail.Pre.Pre.Next = this.Tail
		this.Tail.Pre = this.Tail.Pre.Pre
		this.Size--
		return true
	}
	return false
}

func (this *MyCircularDeque) GetFront() int {
	if this.Size > 0 {
		return this.Head.Next.Val

	}
	return -1
}

func (this *MyCircularDeque) GetRear() int {
	if this.Size > 0 {
		return this.Tail.Pre.Val

	}
	return -1
}

func (this *MyCircularDeque) IsEmpty() bool {
	return this.Size == 0
}

func (this *MyCircularDeque) IsFull() bool {
	return this.Size == this.Cap
}

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * obj := Constructor(k);
 * param_1 := obj.InsertFront(value);
 * param_2 := obj.InsertLast(value);
 * param_3 := obj.DeleteFront();
 * param_4 := obj.DeleteLast();
 * param_5 := obj.GetFront();
 * param_6 := obj.GetRear();
 * param_7 := obj.IsEmpty();
 * param_8 := obj.IsFull();
 */
